//
//  AXHandler.cpp
//  a5game
//
//  Created by Coldwinter on 13-10-14.
//
//

#include "AXHandler.h"

AXHandler::AXHandler():
CCObject(),
m_target(NULL),
m_selector(NULL)
{}

AXHandler* AXHandler::create()
{
    AXHandler* pRet = new AXHandler();
    if( !(pRet && pRet->init()) )
    {
        delete pRet;
        pRet = NULL;
    }
    return pRet;
}

bool AXHandler::init()
{
    // init the mutex lock
    pthread_mutex_init(&m_msg_mutex, NULL);
    //empry queue
    clear();
    //add a message loop 
    CCDirector::sharedDirector()->getScheduler()->scheduleSelector(
               schedule_selector(AXHandler::onDispachMessage),
               this, 0, true);
    return true;
}

CCObject* AXHandler::autorelease()
{
    return NULL;
}

AXHandler::~AXHandler()
{
    clear();
}

void AXHandler::cleanup()
{
    CCDirector::sharedDirector()->getScheduler()->unscheduleSelector(
             schedule_selector(AXHandler::onDispachMessage),this);
    setCallback(NULL,NULL);
}

void AXHandler::postMessage(Message msg)
{
    bool bRet = false;
    pthread_mutex_lock(&m_msg_mutex);
    bRet = m_msg_queue.empty();
    m_msg_queue.push(msg);
    if(bRet)
    {
        CCDirector::sharedDirector()->getScheduler()->resumeTarget(this);//恢复消息循环
    }
    pthread_mutex_unlock(&m_msg_mutex);

}

void AXHandler::postEmptyMessage(int what)
{
    postMessage(Message(what));
}

void AXHandler::setCallback(CCObject* target, SEL_Handler pSelector)
{
    this->m_target = target;
    this->m_selector = pSelector;
}

void AXHandler::clear()
{
    pthread_mutex_lock(&m_msg_mutex);
    while (!m_msg_queue.empty())
    {
        m_msg_queue.pop();
    }
    pthread_mutex_unlock(&m_msg_mutex);
}

void AXHandler::onDispachMessage(float delta)
{
    Message msg;
    bool isEmpty = true;
    pthread_mutex_lock(&m_msg_mutex);
    isEmpty = m_msg_queue.empty();
    if(!isEmpty)
    {
        msg = m_msg_queue.front();
        m_msg_queue.pop();
    }
    if(m_msg_queue.empty())
    {
        // pause the message loop
        CCDirector::sharedDirector()->getScheduler()->pauseTarget(this);
    }
    pthread_mutex_unlock(&m_msg_mutex);

    if(!isEmpty && m_target && m_selector)
    {
        (m_target->*m_selector)(msg);
    }
    
}
